package com.guet; // 定义包名

import javax.swing.*; // 导入用于图形界面组件的包
import java.io.*; // 导入用于文件操作的包
import java.nio.charset.StandardCharsets; // 导入用于字符编码的包
import java.util.*; // 导入用于集合框架和其他实用程序的包
import java.util.List; // 导入用于列表的包

public class fileUse {
    // 开始文件输入缓冲
    private Object[] startFileInputBuf(String path) {
        File file = new File(path); // 创建文件对象
        FileInputStream fis = null; // 文件输入流
        InputStreamReader isr = null; // 输入流读取器
        BufferedReader bfr = null; // 缓冲读取器
        try {
            fis = new FileInputStream(file); // 初始化文件输入流
            isr = new InputStreamReader(fis, StandardCharsets.UTF_8); // 初始化输入流读取器
            bfr = new BufferedReader(isr); // 初始化缓冲读取器
        } catch (IOException e) {
            System.out.println("文件加载错误"); // 捕获IO异常并打印错误信息
        }
        Object[] objs = {(Object) fis, (Object) isr, (Object) bfr}; // 将流对象放入数组
        return objs; // 返回对象数组
    }

    // 开始文件输出缓冲
    private Object[] startFileOutputBuf(String path) {
        File file = new File(path); // 创建文件对象
        FileOutputStream fos = null; // 文件输出流
        OutputStreamWriter osw = null; // 输出流写入器
        BufferedWriter bfw = null; // 缓冲写入器
        try {
            fos = new FileOutputStream(file, true); // 初始化文件输出流（追加模式）
            osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8); // 初始化输出流写入器
            bfw = new BufferedWriter(osw); // 初始化缓冲写入器
        } catch (IOException e) {
            System.out.println("文件加载错误"); // 捕获IO异常并打印错误信息
        }
        Object[] objs = {(Object) fos, (Object) osw, (Object) bfw}; // 将流对象放入数组
        return objs; // 返回对象数组
    }

    // 关闭文件输入缓冲
    private void closeFileInputBuf(Object[] objs) {
        try {
            if (((FileInputStream) objs[0]) != null) ((FileInputStream) objs[0]).close(); // 关闭文件输入流
        } catch (IOException e) {
        }
        try {
            if (((InputStreamReader) objs[1]) != null) ((InputStreamReader) objs[1]).close(); // 关闭输入流读取器
        } catch (IOException e) {
        }
        try {
            if (((BufferedReader) objs[2]) != null) ((BufferedReader) objs[2]).close(); // 关闭缓冲读取器
        } catch (IOException e) {
        }
    }

    // 关闭文件输出缓冲
    private void closeFileOutputBuf(Object[] objs) {
        try {
            if (((FileOutputStream) objs[0]) != null) ((FileOutputStream) objs[0]).close(); // 关闭文件输出流
        } catch (IOException e) {
        }
        try {
            if (((OutputStreamWriter) objs[1]) != null) ((OutputStreamWriter) objs[1]).close(); // 关闭输出流写入器
        } catch (IOException e) {
        }
        try {
            if (((BufferedWriter) objs[2]) != null) ((BufferedWriter) objs[2]).close(); // 关闭缓冲写入器
        } catch (IOException e) {
        }
    }

    // 获取所有节点信息
    public Map<Integer, vexsinfo> getAllVex() {
        Map<Integer, vexsinfo> vexs = new HashMap<>(); // 创建存储节点信息的HashMap
        Object[] objs = startFileInputBuf("resources/vexMessage.txt"); // 开始文件输入缓冲
        BufferedReader bfr = (BufferedReader) objs[2]; // 获取缓冲读取器
        try {
            bfr.readLine(); // 读取文件的第一行（通常是表头）
            String line = bfr.readLine(); // 读取第二行开始的数据
            while (line != null && !line.equals("")) { // 循环读取直到文件末尾
                String[] mess = line.split(" "); // 分割字符串得到节点信息
                vexsinfo vex = new vexsinfo(); // 创建节点信息对象
                vex.id = Integer.valueOf(mess[0]); // 设置节点ID
                vex.name = mess[1]; // 设置节点名称
                vex.realx = Integer.parseInt(mess[2]); // 设置节点实际X坐标
                vex.realy = Integer.parseInt(mess[3]); // 设置节点实际Y坐标
                vex.logicx = Integer.parseInt(mess[4]); // 设置节点逻辑X坐标
                vex.logicy = Integer.parseInt(mess[5]); // 设置节点逻辑Y坐标
                vex.top = Integer.parseInt(mess[6]); // 设置节点上方连接
                vex.bottom = Integer.parseInt(mess[7]); // 设置节点下方连接
                vex.left = Integer.parseInt(mess[8]); // 设置节点左方连接
                vex.right = Integer.parseInt(mess[9]); // 设置节点右方连接
                vex.position = Integer.parseInt(mess[10]); // 设置节点位置
                vex.croded_level = Float.parseFloat(mess[11]); // 设置节点拥挤度
                vex.drive = Integer.parseInt(mess[12]); // 设置节点可通行状态
                vexs.put(vex.id, vex); // 将节点信息放入Map中
                line = bfr.readLine(); // 读取下一行
            }
        } catch (IOException e) {
            System.out.println("读取文件失败" + e.getMessage()); // 捕获IO异常并打印错误信息
        } finally {
            closeFileInputBuf(objs); // 关闭文件输入缓冲
        }
        return vexs; // 返回所有节点信息的Map
    }

    // 获取所有节点名称
    public List<String> getNames() {
        List<String> nameList = new LinkedList<>(); // 创建存储节点名称的列表
        Object[] objs = startFileInputBuf("resources/vexMessage.txt"); // 开始文件输入缓冲
        BufferedReader bfr = (BufferedReader) objs[2]; // 获取缓冲读取器
        try {
            bfr.readLine(); // 读取文件的第一行（通常是表头）
            String line;
            while ((line = bfr.readLine()) != null) { // 循环读取直到文件末尾
                String[] mess = line.split(" "); // 分割字符串得到节点信息
                nameList.add(mess[1]); // 添加节点名称到列表中
            }
        } catch (IOException e) {
        }
        closeFileInputBuf(objs); // 关闭文件输入缓冲
        return nameList; // 返回节点名称列表
    }

    // 根据名称获取节点信息
    public vexsinfo getVexByName(String name) {
        vexsinfo result = new vexsinfo(); // 创建节点信息对象
        Map<Integer, vexsinfo> vexs = getAllVex(); // 获取所有节点信息
        for (vexsinfo v : vexs.values()) { // 遍历所有节点
            if (v.name.equals(name)) { // 如果节点名称匹配
                result = v; // 设置结果为该节点信息
                break; // 退出循环
            }
        }
        return result; // 返回节点信息
    }

    // 设置两点之间的距离
    public void setTwoPointDistance(String name, String name1) {
        Map<Integer, vexsinfo> vexs = getAllVex(); // 获取所有节点信息
        int nameV1 = 0; // 初始化节点1的ID
        int nameV2 = 0; // 初始化节点2的ID
        for (vexsinfo v : vexs.values()) { // 遍历所有节点
            if (v.name.equals(name)) {
                nameV1 = v.id; // 设置节点1的ID
            } else if (v.name.equals(name1)) {
                nameV2 = v.id; // 设置节点2的ID
            }
        }
        Object[] objs = startFileOutputBuf("resources/edge.txt"); // 开始文件输出缓冲
        BufferedWriter bfw = (BufferedWriter) objs[2]; // 获取缓冲写入器
        try {
            String s = JOptionPane.showInputDialog("请输入" + name + "到" + name1 + "的距离:"); // 弹出输入对话框获取距离
            bfw.newLine(); // 写入新行
            if (s != null) bfw.write(nameV1 + " " + nameV2 + " " + s); // 如果输入不为空，写入节点ID和距离
            bfw.flush(); // 刷新缓冲区
        } catch (IOException e) {
        } finally {
            closeFileOutputBuf(objs); // 关闭文件输出缓冲
        }
    }

    // 获取所有边信息
    public List<String> getAllEdge() {
        List<String> list = new LinkedList<>(); // 创建存储边信息的列表
        Object[] objs = startFileInputBuf("resources/edge.txt"); // 开始文件输入缓冲
        BufferedReader bfr = (BufferedReader) objs[2]; // 获取缓冲读取器
        try {
            bfr.readLine(); // 读取文件的第一行（通常是表头）
            String line;
            while ((line = bfr.readLine()) != null) { // 循环读取直到文件末尾
                list.add(line); // 添加边信息到列表中
            }
        } catch (IOException e) {
        }
        closeFileInputBuf(objs); // 关闭文件输入缓冲
        return list; // 返回边信息列表
    }

    // 获取拥挤的节点信息
    public List<String> getCrowded() {
        Object[] objs = startFileInputBuf("resources/crowdedPosition.txt"); // 开始文件输入缓冲
        List<String> list = new ArrayList<>(); // 创建存储拥挤节点的列表
        BufferedReader bfr = (BufferedReader) objs[2]; // 获取缓冲读取器
        String name = "";
        while (true) {
            try {
                if (!((name = bfr.readLine()) != null)) break; // 读取节点信息直到文件末尾
            } catch (IOException e) {
                e.printStackTrace(); // 捕获IO异常并打印堆栈跟踪
            }
            list.add(name); // 添加节点信息到列表中
        }
        closeFileInputBuf(objs); // 关闭文件输入缓冲
        return list; // 返回拥挤节点列表
    }

    // 添加拥挤的节点信息
    public void addCrowded(String name) {
        Object[] objs = startFileOutputBuf("resources/crowdedPosition.txt"); // 开始文件输出缓冲
        BufferedWriter bfr = (BufferedWriter) objs[2]; // 获取缓冲写入器
        try {
            bfr.newLine(); // 写入新行
            bfr.write(name); // 写入节点名称
            bfr.flush(); // 刷新缓冲区
        } catch (IOException e) {
            e.printStackTrace(); // 捕获IO异常并打印堆栈跟踪
        }
        closeFileOutputBuf(objs); // 关闭文件输出缓冲
    }

    // 更新节点的方向信息
    void updateVexDir(int newVexId, String[] dir) {
        BufferedReader bfr = null; // 缓冲读取器
        PrintWriter pw = null; // 打印写入器
        File file = new File("resources/vexMessage.txt"); // 创建文件对象
        StringBuffer buff = new StringBuffer(); // 创建临时容器
        try {
            bfr = new BufferedReader(new FileReader(file)); // 初始化缓冲读取器
            String str = bfr.readLine(); // 读取第一行
            while (str != null && !str.equals("")) { // 循环读取直到文件末尾
                String[] mess = str.split(" "); // 分割字符串得到节点信息
                if (mess[0].equals("49")) {
                    System.out.println("zhe"); // 如果节点ID为49，打印调试信息
                }
                for (int i = 0; i < 4; i++) {
                    if (dir[i].equals("-1")) continue; // 如果方向无效，跳过
                    if (dir[i].equals(mess[1])) { // 如果方向匹配节点名称，更新方向信息
                        switch (i) {
                            case 0:
                                mess[7] = "" + newVexId; // 更新下方向
                                break;
                            case 1:
                                mess[6] = "" + newVexId; // 更新上方向
                                break;
                            case 2:
                                mess[9] = "" + newVexId; // 更新右方向
                                break;
                            case 3:
                                mess[8] = "" + newVexId; // 更新左方向
                                break;
                        }
                    }
                }
                str = ""; // 重置字符串
                for (int j = 0; j < mess.length; j++) str += mess[j] + " "; // 拼接更新后的节点信息
                buff.append(str); // 添加到缓冲区
                str = bfr.readLine(); // 读取下一行
                if (str != null && !str.equals("")) buff.append(System.getProperty("line.separator")); // 添加换行符
                pw = new PrintWriter(new FileWriter(file), true); // 初始化打印写入器
                pw.println(buff); // 打印缓冲区内容到文件
            }
        } catch (IOException e) {
            e.printStackTrace(); // 捕获IO异常并打印堆栈跟踪
        } finally {
            if (bfr != null) {
                try {
                    bfr.close(); // 关闭缓冲读取器
                } catch (IOException e) {
                    e.printStackTrace(); // 捕获IO异常并打印堆栈跟踪
                }
            }
            if (pw != null) pw.close(); // 关闭打印写入器
        }
    }

    // 添加节点信息
    public void addVex(vexsinfo v) {
        Object[] objs = startFileOutputBuf("resources/vexMessage.txt"); // 开始文件输出缓冲
        BufferedWriter bfw = (BufferedWriter) objs[2]; // 获取缓冲写入器
        try {
            String mess = v.id + " " + v.name + " " + v.realx + " " + v.realy + " " + v.logicx + " " + v.logicy + " " + v.top + " " + v.bottom + " " + v.left + " " + v.right + " " + v.position + " " + v.croded_level + " " + v.drive + " " + v.introduction; // 拼接节点信息字符串
            bfw.write(mess); // 写入节点信息
            bfw.flush(); // 刷新缓冲区
        } catch (IOException e) {
            e.printStackTrace(); // 捕获IO异常并打印堆栈跟踪
        }
        closeFileOutputBuf(objs); // 关闭文件输出缓冲
    }
}
